package com.netease.xone.widget;


import java.util.ArrayList;
import java.util.List;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class ActionBar extends RelativeLayout implements OnClickListener{
	private static final boolean DEBUG = true;
	private static final String TAG = ActionBar.class.getSimpleName();

	private int mMoreMenuOffset = 0;
	private int mButtonWidth =0;
	
    /**
     * home容器
     */
    private LinearLayout mLinearLayoutHome;
    /**
     * 返回上一个界面图标
     */
    private View mImageViewHomeBack;
    /**
     * 应用程序图标或主界面图标
     */
    private View mImageViewHomeLogon;
    /**
     * 中间标题容器
     */
    private LinearLayout mLinearLayoutMiddle;
    /**
     * 标题文字
     */
    private TextView mTitle;
    /**
     * Action容器
     */
    private LinearLayout mActionsView;
    private List<Action> mActionList = new ArrayList<Action>();
    
    /**
     * 如果界面排不下ActionButton后出现这按钮
     */
    private ImageButton mOverflowButton;
    /**
     * 点击mOverflowButton后显示的PopupWindow
     */
    private MorePopupWindow mMorePopupWindow;
    
	public ActionBar(Context context) {
		this(context, null);
	}

	public ActionBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	@SuppressWarnings("deprecation")
	private void init() {
		RelativeLayout.LayoutParams params = null;
		LinearLayout ll = null;
		
		/**
		 * 初始化左侧
		 */
		params = new RelativeLayout.LayoutParams(
				RelativeLayout.LayoutParams.WRAP_CONTENT,
				RelativeLayout.LayoutParams.WRAP_CONTENT);
		
		params.addRule(RelativeLayout.CENTER_VERTICAL);
		params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		
		ll = new LinearLayout(getContext());
		ll.setId(0x1fff00);
		ll.setGravity(Gravity.CENTER_VERTICAL);
		ll.setOrientation(LinearLayout.HORIZONTAL);
		ll.setOnClickListener(this);
		mLinearLayoutHome = ll;
		addView(ll, params);
		/**
		 * 初始化中间
		 */
		params = new RelativeLayout.LayoutParams(
				RelativeLayout.LayoutParams.FILL_PARENT,
				RelativeLayout.LayoutParams.WRAP_CONTENT);
		
		params.addRule(RelativeLayout.CENTER_VERTICAL);
		params.addRule(RelativeLayout.RIGHT_OF, 0x1fff00);
		params.addRule(RelativeLayout.LEFT_OF, 0x1fff02);
		
		ll = new LinearLayout(getContext());
		ll.setId(0x1fff01);
		ll.setGravity(Gravity.CENTER_VERTICAL);
		ll.setOrientation(LinearLayout.HORIZONTAL);
		ll.setOnClickListener(this);
		mLinearLayoutMiddle = ll;
		addView(ll, params);
		/**
		 * 初始化右侧
		 */
		params = new RelativeLayout.LayoutParams(
				RelativeLayout.LayoutParams.WRAP_CONTENT,
				RelativeLayout.LayoutParams.WRAP_CONTENT);
		
		params.addRule(RelativeLayout.CENTER_VERTICAL);
		params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		
		ll = new LinearLayout(getContext());
		ll.setId(0x1fff02);
		ll.setGravity(Gravity.CENTER_VERTICAL);
		ll.setOrientation(LinearLayout.HORIZONTAL);
		ll.setOnClickListener(this);
		mActionsView = ll;
		addView(ll, params);
		
		setGravity(Gravity.CENTER);
        createOverflowActionButton();
	}

	private void createOverflowActionButton() {
		final ActionBar mActionBar = this;
		mOverflowButton = new ImageButton(getContext());
		mOverflowButton.setBackgroundDrawable(null);
		mOverflowButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				mOverflowButton.setAnimation(null);
				if (mMorePopupWindow == null || !mMorePopupWindow.isShowing()) {
					mMorePopupWindow = new MorePopupWindow(getContext(),mActionBar);
					mMorePopupWindow.setOnDismissListener(new OnDismissListener() {

								public void onDismiss() {
									/**
									 * 清空子View是为了解决再次创建PopupWindow时可以重复加入
									 */
									if (mMorePopupWindow.getContentView() instanceof ViewGroup) {
										ViewGroup vg = (ViewGroup)mMorePopupWindow.getContentView();
										vg.removeAllViews();
									}
									mMorePopupWindow = null;
								}
							});

				} else {
					mMorePopupWindow.dismiss();
				}
			}
		});
	}
	
	@Override
	public void onClick(View view) {
		if (DEBUG) {
			Log.d(TAG, view.toString());
		}
		
		final Object tag = view.getTag();
        if (tag instanceof Action) {
            final Action action = (Action) tag;
            action.performAction(view);
        } else {
        	if (view instanceof ViewGroup) {
        		ViewGroup vg = (ViewGroup)view;
        		for (int index = 0; index < vg.getChildCount(); index++) {
        			onClick(vg.getChildAt(index));
        		}
        	}
        }
	}
	
	public void setOverflowButtonImageAndWith(int resId, int dimen) {
		mOverflowButton.setImageResource(resId);
		mButtonWidth = getResources().getDimensionPixelSize(dimen);
		
	}
	
	public ActionBar setHomeOnClickListener(OnClickListener click) {
		mLinearLayoutHome.setOnClickListener(click);
		return this;
	}
	
	public ActionBar setHomeVisibility(int visibility) {
		mLinearLayoutHome.setVisibility(visibility);
		return this;
	}
	
	public ActionBar setHomeBackVisibility(int visibility) {
		mImageViewHomeBack.setVisibility(visibility);
		return this;
	}
	
	public ActionBar setHomeBack(int resId) {
		if (null != mImageViewHomeBack 
				&& mImageViewHomeBack instanceof ImageButton) {
			((ImageButton)mImageViewHomeBack).setImageResource(resId);
		}
		return this;
	}
	
	public ActionBar setHomeLogo(int resId) {
		if (null != mImageViewHomeLogon 
				&& mImageViewHomeLogon instanceof ImageButton) {
			((ImageButton)mImageViewHomeLogon).setImageResource(resId);
		}
		return this;
	}
	
	public ActionBar setTitleVisibility(int visibility) {
		mTitle.setVisibility(visibility);
        return this;
    }
	
	public ActionBar setTitle(int titleRes) {
		setTitle(getContext().getString(titleRes));
		return this;
	}

	public ActionBar setTitle(CharSequence title) {
		mTitle.setText(title);
		return this;
	}
	
	public TextView getTitle(){
		return mTitle;
	}
	
	public ActionBar addHomeBack(Action action) {
		if (null != mImageViewHomeBack) {
			mLinearLayoutHome.removeView(mImageViewHomeBack);
		}
		
		mImageViewHomeBack = createViewFromAction(action);
		mImageViewHomeBack.setClickable(false);
		mLinearLayoutHome.addView(mImageViewHomeBack, 0);
		return this;
	}
	
	public ActionBar addHomeLogo(Action action) {
		if (null != mImageViewHomeLogon) {
			mLinearLayoutHome.removeView(mImageViewHomeLogon);
		}
		
		mImageViewHomeLogon = createViewFromAction(action);
		mImageViewHomeLogon.setClickable(false);
		mLinearLayoutHome.addView(mImageViewHomeLogon);
		return this;
	}
	
	public ActionBar addTitle(Action action) {
		if (null != mTitle) {
			mLinearLayoutMiddle.removeView(mTitle);
		}
		
		mTitle = (TextView)createViewFromAction(action);
		mTitle.setId(0);
		mTitle.setClickable(false);
		mLinearLayoutMiddle.addView(mTitle);
		return this;
	}
	
	public ActionBar addMiddleAction(Action action) {
		mLinearLayoutMiddle.addView(createViewFromAction(action));
		return this;
	}
	
	public ActionBar addAction(Action action) {
		mActionList.add(action);
		resetActionViews(getMeasuredWidth(), mButtonWidth);
		return this;
	}
	
	public ActionBar addAction(Action action, int index) {
		mActionList.add(index, action);
		resetActionViews(getMeasuredWidth(), mButtonWidth);
		return this;
	}
	
	public ActionBar addActions(List<Action> list) {
		mActionList.addAll(list);
		resetActionViews(getMeasuredWidth(), mButtonWidth);
		return this;
	}
	
	public Action getAction(int index) {
		return mActionList.get(index);
	}
	
	public View createViewFromAction(Action action) {
		View v = null;
		v = action.createView();
		v.setOnClickListener(this);
		v.setTag(action);
		return v;
	}
	
	public ActionBar removeAction(int index) {
		mActionList.remove(index);
		resetActionViews(getMeasuredWidth(), mButtonWidth);
		return this;
	}
	
	public ActionBar removeAction(Action action) {
		mActionList.remove(action);
		resetActionViews(getMeasuredWidth(), mButtonWidth);
		return this;
	}
	
	public ActionBar removeAllActions() {
		mActionList.clear();
		mActionsView.removeAllViewsInLayout();
		return this;
	}
	
	private void resetActionViews(int actionsWidth, int buttonWidth) {
		mActionsView.removeAllViews();
		int num_actions = mActionList.size();
		if (num_actions > 0 && actionsWidth > 0) {
			
			/**
			 * 按钮个数
			 */
			int buttonNum = actionsWidth/2/buttonWidth;
			
			if (buttonNum >= num_actions) {
				mActionsView.addView(mOverflowButton);
				mOverflowButton.setVisibility(View.INVISIBLE);
				for(Action action : mActionList) {
					mActionsView.addView(createViewFromAction(action));
				}
			} else {
				mMoreMenuOffset = buttonNum-1;
				for (int i = 0; i < buttonNum-1; i++) {
					mActionsView.addView(createViewFromAction(mActionList.get(i)));
				}
				mActionsView.addView(mOverflowButton);
				mOverflowButton.setVisibility(View.VISIBLE);
			}
		}
	}
	
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		
		if (mActionsView.getChildCount() > 0) {
			return;
		}
		
		resetActionViews(r-l, mButtonWidth);
	}
	
	public int getMoreMenuOffset() {
		return mMoreMenuOffset;
	}
	
	public int getActionCount() {
		return mActionList.size();
	}
	
	public void clear() {
		mLinearLayoutHome = null;
		mImageViewHomeBack = null;
		mImageViewHomeLogon = null;
		mLinearLayoutMiddle = null;
	    mTitle = null;
	    mActionsView = null;
	    if (null != mActionList) {
	    	for (Action action : mActionList) {
	    		action.clear();
	    	}
	    	mActionList.clear();
	    }
	    mActionList = null;
	    mOverflowButton = null;
	    if (null != mMorePopupWindow && mMorePopupWindow.isShowing()) {
	    	mMorePopupWindow.dismiss();
	    }
	    mMorePopupWindow = null;
	}
	
	public interface Action {
		public void clear();
		public View createView();
		
		public View getView();

		public boolean performAction(View view);
	}

	public static abstract class ClickAction implements Action {
		private OnClickListener mOnClickListener;
		public ClickAction(OnClickListener click) {
			mOnClickListener = click;
		}

		public void setOnclickListener(OnClickListener click) {
			mOnClickListener = click;
		}
		
		@Override
		public boolean performAction(View view) {
			boolean bRes = false;
			if (null != mOnClickListener) {
				mOnClickListener.onClick(view);
				bRes = true;
			}
			
			return bRes;
		}
		
		@Override
		public void clear() {
			mOnClickListener = null;
		}
	}
	
	public static class ImageViewAction extends ClickAction {
		private final int mDrawable;
		private Context mContext;
		
		private ImageView mImageView;

		public ImageViewAction(Context context, OnClickListener click, int drawable) {
			super(click);
			mContext = context;
			mDrawable = drawable;
		}

		@Override
		public View createView() {
			if (null != mImageView) {
				return mImageView;
			}
			
			ImageView v = null;
			v = new ImageView(mContext);
			v.setImageResource(mDrawable);
			mImageView = v;
			return mImageView;
		}
		
		@Override
		public View getView() {
			return mImageView;
		}
		
		public Context getContext() {
			return mContext;
		}
		
		@Override
		public void clear() {
			super.clear();
			mContext = null;
			mImageView = null;
		}
	}
	
	public static class ImageButtonAction extends ClickAction {
		private final int mDrawable;
		private Context mContext;
		
		private ImageButton mImageButton;

		public ImageButtonAction(Context context, OnClickListener click, int drawable) {
			super(click);
			mContext = context;
			mDrawable = drawable;
		}

		@Override
		public View createView() {
			if (null != mImageButton) {
				return mImageButton;
			}
			
			ImageButton v = null;
			v = new ImageButton(mContext);
			v.setImageResource(mDrawable);
			v.setBackground(null);
			mImageButton = v;
			return mImageButton;
		}
		
		@Override
		public View getView() {
			return mImageButton;
		}
		
		public Context getContext() {
			return mContext;
		}
		
		@Override
		public void clear() {
			super.clear();
			mContext = null;
			mImageButton = null;
		}
	}

	public static class TextViewAction extends ClickAction {
		private TextView mTextView;
		
		public TextViewAction(TextView textView, OnClickListener click) {
			super(click);
			mTextView = textView;
		}
		
		@Override
		public View createView() {
			return mTextView;
		}
		
		@Override
		public View getView() {
			return mTextView;
		}
		
		@Override
		public void clear() {
			super.clear();
			mTextView = null;
		}
	}
	
	public static class IntentAction extends ImageButtonAction {
		private final Intent mIntent;

		public IntentAction(Context context, Intent intent, int drawable) {
			super(context, null, drawable);
			mIntent = intent;
		}

		@Override
		public boolean performAction(View view) {
			boolean bRes = false;
			try {
				if (null != getContext()) {
					getContext().startActivity(mIntent);
				}
				bRes = true;
			} catch (ActivityNotFoundException e) {
				e.printStackTrace();
			}
			
			return bRes;
		}
	}
	
	public static class MorePopupWindow extends PopupWindow implements OnClickListener {

		private final ActionBar mActionBar;

		public MorePopupWindow(Context context, ActionBar ab) {
			super(context);

			mActionBar = ab;
			setAnimationStyle(0);
			setTouchable(true);
			setFocusable(true);

			LinearLayout layout = new LinearLayout(context);
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.WRAP_CONTENT,
					LinearLayout.LayoutParams.WRAP_CONTENT);
			layout.setLayoutParams(lp);
			layout.setOrientation(LinearLayout.VERTICAL);

			for (int i = mActionBar.getMoreMenuOffset(); i < mActionBar.getActionCount(); i++) {
				View v = mActionBar.createViewFromAction(mActionBar.getAction(i));
				v.setId(i);
				v.setOnClickListener(this);
				layout.addView(v);
			}

			setContentView(layout);
			layout.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
			setHeight(layout.getMeasuredHeight());
			setWidth(layout.getMeasuredWidth());
			showAsDropDown(mActionBar, ab.getMeasuredWidth()-layout.getMeasuredWidth(), 0);

		}

		public void onClick(View view) {
			final Object tag = view.getTag();
	        if (tag instanceof Action) {
	            final Action action = (Action) tag;
	            action.performAction(view);
	        }
			dismiss();
		}
	}
}
